# coding=utf-8

import socket
import select
import threading

from CommandHandler import CommandHandler

PORT = 4333     # 端口号
NAME = "Lobby"  # 主聊天室（大厅）名称


# 服务器
class ChatServer:

    def __init__(self, port=PORT, name=NAME):
        self.server = socket.socket()
        host = socket.gethostname()
        print "Host name =", host
        self.server.bind((host, port))
        self.server.listen(5)
        self.all_sock = [self.server, ]
        self.name = name
        self.command_handler = CommandHandler(name)
        self.exitcode = 0
        try:
            self._perform()
        finally:
            self._close()

    # 建立连接，新建会话
    def _connect(self):
        client, address = self.server.accept()
        print "Got connection from", address
        self.all_sock.append(client)
        self.command_handler.add_session(client)

    # 断开连接，登出及用户数据保存等
    def _disconnect(self, client):
        self.all_sock.remove(client)
        self.command_handler.disconnect(client)
        print client.getpeername(), "disconnected"

    # 断开所有连接（由于断开单个连接中有remove函数，还没想到更好的解决办法，先再写一个函数）
    def _disconnect_all(self):
        while self.all_sock:
            client = self.all_sock.pop()
            if client is not self.server:
                self.command_handler.disconnect(client)
                print client.getpeername(), "disconnected"

    # 服务器关闭时需要处理的一些行为
    def _close(self):
        print "close"
        self._disconnect_all()
        # 最后运行该函数，目前的功能是关闭数据库
        self.command_handler.close()

    # 主循环，处理来自网络的消息
    def _loop(self):
        while True:
            if self.exitcode:
                break
            self.command_handler.process_game()
            read_socks, write_socks, expect_socks = select.select(self.all_sock, [], [], 1)
            for read_sock in read_socks:
                if read_sock is self.server:
                    self._connect()
                else:
                    try:
                        data = read_sock.recv(1024)
                        disconnected = not data
                    except socket.error:
                        disconnected = True
                    if disconnected:
                        self._disconnect(read_sock)
                    else:
                        self.command_handler.handle_data(read_sock, data)

    # 服务端获取键盘输入，目前主要功能是用quit命令关闭服务器
    def _input(self):
        while True:
            line = raw_input()
            print "Server: %s" % line
            if line == "quit":
                self.exitcode = 1
                break
            # elif line == "begin":
            #     self.command_handler.begin_game()

    def _perform(self):
        thread1 = threading.Thread(target=self._loop)
        # thread2 = threading.Thread(target=self._input)
        # thread1.setDaemon(True)
        thread1.start()
        # thread2.start()
        self._input()

if __name__ == "__main__":
    chat_server = ChatServer(PORT, NAME)
